using System;
using System.Collections.Generic;
using System.Text;
using IWS.Lib.SingleSignOn.ServiceResponses;
using System.IO;
using IWS.Lib.SingleSignOn.Exceptions;

namespace IWS.Lib.SingleSignOn
{
	/// <summary>
	/// Web service role provider. 
	/// </summary>
	public class WebServiceRoleProvider : System.Web.Security.RoleProvider
	{
		private string sServiceKey;

		/// <summary>
		/// Create an instance of the web service role provider
		/// </summary>
		public WebServiceRoleProvider()
		{
			this.sServiceKey = String.Empty;
		}

		private string[] GetStringArray(object[] array)
		{
			if (array != null)
			{
				string[] list = new string[array.Length];
				for (int ix = 0; ix < array.Length; ix++)
				{
					list[ix] = array[ix].ToString();
				}
				return list;
			}
			else
			{
				return null;
			}
		}

		/// <summary>
		/// Initialize the provider. 
		/// </summary>
		/// <remarks>Part of the initialization process includes establishing a session with the remote provider for security.</remarks>
		/// <param name="name"></param>
		/// <param name="config"></param>
		public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
		{
			base.Initialize(name, config);

			//read key. 
			string filename = IWS.Lib.SingleSignOn.MediumTrustSecurity.ResolveKeyFile(System.Configuration.ConfigurationManager.AppSettings["WebServiceKeyFile"]);
			this.sServiceKey = IWS.Lib.SingleSignOn.MediumTrustSecurity.ReadKeyFile(filename);
		}

		public override void AddUsersToRoles(string[] usernames, string[] roleNames)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ServiceResponse resp = svc.AddUsersToRoles(this.sServiceKey, usernames, roleNames);
			if (resp.Result != ServiceResponse.eResult.Success)
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override string ApplicationName
		{
			get
			{
				RoleWebService.RoleService svc = new RoleWebService.RoleService();
				ServiceResponse resp = svc.GetApplicationName(this.sServiceKey);
				if (resp.Result == ServiceResponse.eResult.Success)
				{
					if (resp.Data != null)
						return resp.Data.ToString();
					else
						throw new ServiceException("Response contains no data.");
				}
				else
					throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
			}
			set
			{
				RoleWebService.RoleService svc = new RoleWebService.RoleService();
				ServiceResponse resp = svc.SetApplicationName(this.sServiceKey, value);
				if (resp.Result != ServiceResponse.eResult.Success)
					throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
			}
		}

		public override void CreateRole(string roleName)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ServiceResponse resp = svc.CreateRole(this.sServiceKey, roleName);
			if (resp.Result != ServiceResponse.eResult.Success)
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ServiceResponse resp = svc.DeleteRole(this.sServiceKey, roleName, throwOnPopulatedRole);
			if (resp.Result == ServiceResponse.eResult.Success)
			{
				if (resp.Data != null)
					return (bool)resp.Data;
				else
					throw new ServiceException("Response contains no data.");
			}
			else
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override string[] FindUsersInRole(string roleName, string usernameToMatch)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ArrayServiceResponse resp = svc.FindUsersInRole(this.sServiceKey, roleName, usernameToMatch);
			if (resp.Result == ServiceResponse.eResult.Success)
			{
				return GetStringArray(resp.Data);
			}
			else
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override string[] GetAllRoles()
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ArrayServiceResponse resp = svc.GetAllRoles(this.sServiceKey);
			if (resp.Result == ServiceResponse.eResult.Success)
			{
				return GetStringArray(resp.Data);
			}
			else
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override string[] GetRolesForUser(string username)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ArrayServiceResponse resp = svc.GetRolesForUser(this.sServiceKey, username);
			if (resp.Result == ServiceResponse.eResult.Success)
			{
				return GetStringArray(resp.Data);
			}
			else
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override string[] GetUsersInRole(string roleName)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ArrayServiceResponse resp = svc.GetUsersInRole(this.sServiceKey, roleName);
			if (resp.Result == ServiceResponse.eResult.Success)
			{
				return GetStringArray(resp.Data);
			}
			else
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override bool IsUserInRole(string username, string roleName)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ServiceResponse resp = svc.IsUserInRole(this.sServiceKey, username, roleName);
			if (resp.Result == ServiceResponse.eResult.Success)
			{
				if (resp.Data != null)
					return (bool)resp.Data;
				else
					throw new ServiceException("Response contains no data.");
			}
			else
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ServiceResponse resp = svc.RemoveUsersFromRoles(this.sServiceKey, usernames, roleNames);
			if (resp.Result != ServiceResponse.eResult.Success)
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}

		public override bool RoleExists(string roleName)
		{
			RoleWebService.RoleService svc = new RoleWebService.RoleService();
			ServiceResponse resp = svc.RoleExists(this.sServiceKey, roleName);
			if (resp.Result == ServiceResponse.eResult.Success)
			{
				if (resp.Data != null)
					return (bool)resp.Data;
				else
					throw new ServiceException("Response contains no data.");
			}
			else
				throw new ServiceException(resp.Result.ToString() + ": " + resp.Message);
		}
	}
}
